package com.cmbchina.encrypt;

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import java.io.*;
import java.security.Security;

import static com.cmbchina.encrypt.SM4.PROVIDER;

/**
 * SM3
 *
 * @author liuxb
 * @date 2022/1/17 17:19
 */
public class SM3 {
    public SM3() {
    }

    public static SM3 getInstance() {
        Security.addProvider(PROVIDER);
        return new SM3();
    }

    public byte[] CMBSM3Digest(byte[] msg) throws SMCryptException {
        if (msg == null) {
            throw new SMCryptKYException(ErrorCode.E10400);
        } else if (msg.length <= 0) {
            throw new SMCryptKYException(ErrorCode.E10415);
        } else {
            byte[] bytes = new byte[32];
            SM3Digest digest = new SM3Digest();
            digest.update(msg, 0, msg.length);
            digest.doFinal(bytes, 0);
            digest.reset();
            return bytes;
        }
    }

    public byte[] CMBSM3HMAC(byte[] key, byte[] msg) throws SMCryptException {
        if (msg == null) {
            throw new SMCryptKYException(ErrorCode.E10400);
        } else if (key == null) {
            throw new SMCryptKYException(ErrorCode.E10400);
        } else if (msg.length <= 0) {
            throw new SMCryptKYException(ErrorCode.E10415);
        } else if (key.length != 64) {
            throw new SMCryptKYException(ErrorCode.E10423);
        } else {
            SM3Digest sm3 = new SM3Digest();
            HMac h = new HMac(sm3);
            byte[] bytes = new byte[32];
            KeyParameter params = new KeyParameter(key);
            h.init(params);
            h.update(msg, 0, msg.length);
            h.doFinal(bytes, 0);
            h.reset();
            return bytes;
        }
    }

    public byte[] CMBSM3FileDigest(String file) throws SMCryptException {
        if (file == null) {
            throw new SMCryptKYException(ErrorCode.E10400);
        } else {
            File f = new File(file);
            if (!f.exists()) {
                throw new SMCryptKYException(ErrorCode.E10109, "Path: " + file);
            } else if (file.length() > 260) {
                throw new SMCryptKYException(ErrorCode.E10108, "Excepted file length.Path: " + file);
            } else if (!f.isFile()) {
                throw new SMCryptKYException(ErrorCode.E10109, "Excepted file,actual directory. Path: " + file);
            } else if (!f.canRead()) {
                throw new SMCryptKYException(ErrorCode.E10104, "Path: " + file);
            } else {
                BufferedInputStream stream = null;
                try {
                    stream = new BufferedInputStream(new FileInputStream(file));
                    byte[] bytes = new byte[32];
                    SM3Digest digest = new SM3Digest();
                    byte[] buffer = new byte[4096];
                    int size;
                    do {
                        size = stream.read(buffer);
                        digest.update(buffer, 0, size);
                    } while (size == 4096);
                    digest.doFinal(bytes, 0);
                    digest.reset();
                    byte[] var9 = bytes;
                    return var9;
                } catch (FileNotFoundException var17) {
                    if (f.exists() && f.isFile()) {
                        throw new SMCryptKYException(ErrorCode.E10104);
                    } else {
                        throw new SMCryptKYException(ErrorCode.E10109, var17);
                    }
                } catch (IOException var18) {
                    throw new SMCryptKYException(ErrorCode.E10104, var18);
                } finally {
                    if (stream != null) {
                        try {
                            stream.close();
                        } catch (Exception var16) {
                        }
                    }
                }
            }
        }
    }
}